// 基类
var ai = function() {
};
ai.prototype = {};

// 应用平台赢的概率
ai.prototype.checkRatio = function(rate) {
    if (Math.random() < rate) return true;
    return false;
}

// 将互斥的下注项中和下，并按下注额排序
ai.prototype.mixBets = function(bets, keys) {
    var self = this;
    for (var i in keys) {
        var k1 = keys[i][0], k2 = keys[i][1];
        if (!bets[k1] || !bets[k2]) continue;

        if (bets[k1] > bets[k2]) {
            bets[k1] -= bets[k2];
            bets[k2] = 0;
        }
        else {
            bets[k2] -= bets[k1];
            bets[k1] = 0;
        }
    }

    var list = [];
    for (var k in bets) {
        if (!bets[k]) continue;
        var rate = 3.81;
        if (self.map[k]) rate = self.map[k].rate;
        list.push({
            key: k,
            amount: bets[k] * rate,
        })
    }
    list.sort(function(a, b) {
        return b.amount - a.amount;
    });
    return list;
}

// 优先开出got的号码，如果不行就直接无视
ai.prototype.prior = function(arr, got) {
    var list = [];
    for (var i = 0; i < got.length; i++) {
        if (arr.indexOf(got[i]) != -1) {
            list.push(got[i]);
        }
    }
    if (list.length > 0) return list;
    return arr;
}

// 删除掉一个项目
ai.prototype.deleteItem = function(arr, n) {
    var index = arr.indexOf(n);
    if (index >= 0) arr.splice(index, 1);
}

// 数组中随机抽取一个
ai.prototype.random = function(arr) {
    var index = parseInt(Math.random() * arr.length);
    if (index >= arr.length) index = arr.length - 1;
    return arr[index];
}

ai.prototype.isEmpty = function(d) {
    if (!d) return true;
    Object.keys(d).length == 0;
}

ai.prototype.range = function(min, max) {
    var arr = [];
    for (var i = min; i <= max; i++) arr.push(i);
    return arr;
}

//-------------------------------------------------------------------------------------
// PK10的开奖AI
var pk10Ai = function() {
    this.arr2 = ['冠', '亚', '三', '四', '五', '六', '七', '八', '九', '十'];
    this.arr4 = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
    ai.call(this);
};
pk10Ai.prototype = Object.create(ai.prototype);

// 记录到受影响的行
pk10Ai.prototype.insertToNumber = function(list) {
    // 记录到各受影响的号码
    var result = [];
    for (var i = 0; i < 10; i++) {
        result[i] = {
            index: i + 1,
            total: 0,
            bet: [],
        };
    }
    for (var i in list) {
        var k = list[i].key;
        if (k.startsWith("冠亚")) {
            result[0].bet.push(k);
            result[1].bet.push(k);
            result[0].total += list[i].amount;
            result[1].total += list[i].amount;
        }
        else {
            var index = this.arr2.indexOf(k[0]);
            result[index].bet.push(k);
            result[index].total += list[i].amount;

            if (k[1] == '龙' || k[2] == '虎') {
                result[9 - index].bet.push(k);
                result[9 - index].total += list[i].amount;
            }
        }
    }
    result.sort(function(a, b) {
        return b.total - a.total;
    });
    return result;
}

// 检测某个投注项，并应用概率
pk10Ai.prototype.apply = function(key, key2, arr1, arr2, all) {
    var self = this;
    if (key != key2) return null;
    if (this.checkRatio(self.rate)) {
        all = self.prior(all, arr1);
    }
    else {
        all = self.prior(all, arr2);
    }
    return all;
}

// 应用龙虎的概率，需要将信息记录到另外个关联号码
// lh - 用户的投注  lh2 - 实际开奖结果
pk10Ai.prototype.longhu = function(result, index, lh, lh2) {
    var self = this;
    var index2 = 11 - index;
    for (var i in result) {
        if (result[i].index != index2) continue;
        var data = result[i];

        self.deleteItem(data.bet, lh);
        if (!data.pre) data.pre = [lh2];
        else data.pre.push(lh2);
    }
}

// 取得龙虎的开奖数据
pk10Ai.prototype.longhuNumbers = function(index, lh, ns) {
    var index2 = 11 - index;
    var n = ns[index2 - 1];

    var arr = [];
    if (lh == '龙' && index < index2 || lh == '虎' && index > index2) {
        // 需要大于n
        for (var i = n + 1; i <= 10; i++) arr.push(i);
    }
    else {
        // 需要小于n
        for (var i = 1; i < n; i++) arr.push(i);
    }
    return arr;
}

// 应用冠亚的概率，需要将信息记录到另外个关联号码
// gy - 用户的投注  gy2 - 实际开奖结果
pk10Ai.prototype.guanya = function(result, index, gy, gy2) {
    var self = this;
    var index2 = index == 1 ? 2 : 1;
    for (var i in result) {
        if (result[i].index != index2) continue;
        var data = result[i];

        self.deleteItem(data.bet, gy);
        if (!data.pre) data.pre = [gy2];
        else data.pre.push(gy2);
    }

    // 返回期望开出来的号码
    if (gy2 == '冠亚大') return [5, 6, 7, 8, 9, 10];
    if (gy2 == '冠亚小') return [1, 2, 3, 4, 5, 6];
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}

// 取得冠亚的开奖数据
pk10Ai.prototype.guanyaNumbers = function(index, gy, ns) {
    var index2 = index == 1 ? 2 : 1;
    var n = ns[index2 - 1];

    var arr = [];
    if (gy == '冠亚大') {
        // >11
        for (var i = 12 - n; i <= 10; i++) arr.push(i);
    }
    else if (gy == '冠亚小') {
        // <= 11
        for (var i = 1; i <= 11 - n; i++) arr.push(i);
    }
    else if (gy == '冠亚单' && n % 2 == 0 || gy == '冠亚双' && n % 2 == 1) {
        arr = [1, 3, 5, 7, 9];
    }
    else if (gy == '冠亚单' && n % 2 == 1 || gy == '冠亚双' && n % 2 == 0) {
        arr = [2, 4, 6, 8, 10];
    }
    else {
        // 冠亚和
        var he = parseInt(gy.substring(2));
        if (he == 0) {
            // 随机开
            arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
            return;
        }

        for (var i = 1; i <= 10; i++) {
            if (i != he - n) arr.push(i);
        }
    }
    return arr;
}

// 入口
pk10Ai.prototype.open = function(bets, lottery, rate) {
    var self = this;
    self.map = lottery;
    self.rate = rate;
    
    // 合并下数据
    var arr = [["冠亚大", "冠亚小"], ["冠亚单", "冠亚双"]];
    var arr2 = self.arr2;
    var arr4 = self.arr4;
    for (var i in arr2) {
        var k = arr2[i];
        arr.push([k + "大", k + "小"]);
        arr.push([k + "单", k + "双"]);
        arr.push([k + "龙", k + "虎"]);
    }
    var list = self.mixBets(bets, arr);

    // 记录到各受影响的号码
    var result = self.insertToNumber(list);

    // 逐个号码开出来
    var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    var lottery = [];
    var ns = [];
    for (var i in result) {
        var index = result[i].index;
        var bets = result[i].bet;
        if (self.isEmpty(bets) && self.isEmpty(result[i].pre)) continue;

        var all = numbers.concat([]);
        if (result[i].pre) {
            // 这些受其他号码影响，需要优先处理
            for (var j in result[i].pre) {
                var k = result[i].pre[j];
                if (k == '龙' || k == '虎') {
                    all = self.prior(all, self.longhuNumbers(index, k, ns));
                }
                else {
                    // 只能是冠亚的了
                    all = self.prior(all, self.guanyaNumbers(index, k, ns));
                }
            }
        }
        for (var j in bets) {
            var k = bets[j];
            if (!k) continue;
            var k2 = k[1];
            do {
                if (k == '冠亚大') {
                    if (self.checkRatio(rate)) self.guanya(result, index, k, '冠亚小');
                    else self.longhu(result, index, k, '冠亚大');
                    break;
                }
                if (k == '冠亚小') {
                    if (self.checkRatio(rate)) self.guanya(result, index, k, '冠亚大');
                    else self.longhu(result, index, k, '冠亚小');
                    break;
                }
                if (k == '冠亚单') {
                    if (self.checkRatio(rate)) self.guanya(result, index, k, '冠亚双');
                    else self.longhu(result, index, k, '冠亚单');
                    break;
                }
                if (k == '冠亚双') {
                    if (self.checkRatio(rate)) self.guanya(result, index, k, '冠亚单');
                    else self.longhu(result, index, k, '冠亚双');
                    break;
                }
                if (k.startsWith("冠亚")) {
                    // 冠亚和
                    if (rate > 0.5) {
                        // 直接不让中
                        self.guanya(result, index, k, k);
                    }
                    else self.guanya(result, index, k, "冠亚0");
                }

                var t = self.apply(k2, "大", [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], all);
                if (t != null) { all = t; break; }

                var t = self.apply(k2, "小", [6, 7, 8, 9, 10], [1, 2, 3, 4, 5], all);
                if (t != null) { all = t; break; }

                var t = self.apply(k2, "单", [2, 4, 6, 8, 10], [1, 3, 5, 7, 9], all);
                if (t != null) { all = t; break; }

                var t = self.apply(k2, "双", [1, 3, 5, 7, 9], [2, 4, 6, 8, 10], all);
                if (t != null) { all = t; break; }

                if (k2 == '龙') {
                    // 交给另外一个号码去处理
                    if (self.checkRatio(rate)) self.longhu(result, index, k2, '虎');
                    else self.longhu(result, index, k2, '龙');
                    break;
                }
                if (k2 == '虎') {
                    // 交给另外一个号码去处理
                    if (self.checkRatio(rate)) self.longhu(result, index, k2, '龙');
                    else self.longhu(result, index, k2, '虎');
                    break;
                }

                if (arr4.indexOf(k2) != -1) {
                    // 正码
                    var n = arr4.indexOf(k2) + 1;
                    var p = (9 * rate) / (9 * rate + 1 - rate);
                    if (self.checkRatio(p)) {
                        var temp = [];
                        for (var m = 1; m <= 10; m++) if (m != n) temp.push(m);
                        all = self.prior(all, temp);
                    }
                    else {
                        all = self.prior(all, [n]);
                    }
                    break;
                }
            } while (false);
            if (all.length == 1) break;
        }

        // 应用概率，抽取一个出来
        ns[index - 1] = self.random(all);
        self.deleteItem(numbers, ns[index - 1]);
    }

    // 还没有开出的号码，随机开了
    for (var i = 0; i < 10; i++) {
        if (ns[i] !== undefined) continue;

        ns[i] = self.random(numbers);
        self.deleteItem(numbers, ns[i]);
    }

    // 返回开奖结果
    return ns;
}
var Pk10Ai = new pk10Ai();

/**
 * 请求开奖的接口
 * @bets: 下注信息，例如：
 *   {冠亚大: 10, 冠亚小: 5 }
 * @lottery: 赔率信息，例如： {冠亚大:2.33}
 * @rate: 杀率，例如：0.6（60%的杀率）
 */
function openAI(game, bets, lottery, rate) {
    if (game == 'zypk10') {
        return Pk10Ai.open(bets, lottery, rate);
    }
    if (game == 'zyssc') {
        return SscAi.open(bets, lottery, rate);
    }
    if (game == 'zy115') {
        return ElevenAi.open(bets, lottery, rate);
    }
    if (game == 'zyk3') {
        return Kuai3Ai.open(bets, lottery, rate);
    }
    if (game == 'zykl10') {
        return TenAi.open(bets, lottery, rate);
    }
    if (game == 'zykl8') {
        return Kl8Ai.open(bets, lottery, rate);
    }
}

function testAi() {
    var bets = {
        十三: 100,
        十四: 100,
        十五: 100,
        十六: 100,
        十七: 100,
    }
    return Pk10Ai.open(bets, Zypk10Rule.map, 0.9);
}